package components;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.dom4j.Element;
import org.dom4j.ElementHandler;

public class LinguisticValue {
	private ArrayList<Pair<Double, Double>> points = new ArrayList<Pair<Double, Double>>();

	public ArrayList<Pair<Double, Double>> getPoints() {
		return points;
	}

	public void setPoints(ArrayList<Pair<Double, Double>> points) {
		this.points = points;
	}

	private int distanceOfXString = 5;
	private String name = "";
	private Element ele = null;
	private Color color = Color.BLACK;

	public LinguisticValue(Element ele) {
		this.ele = ele;
		name = ele.attributeValue("name");
		List<Element> list = ele.elements("point");
		for (Element e : list) {
			double x = Double.parseDouble(e.attributeValue("x"));
			double y = Double.parseDouble(e.attributeValue("y"));
			Pair<Double, Double> p = new Pair(x, y);
			points.add(p);
		}
		Collections.sort(points, new Comparator<Pair<Double, Double>>() {

			@Override
			public int compare(Pair<Double, Double> o1, Pair<Double, Double> o2) {
				return o1.first > o2.first ? 1 : -1;
			}

		});

	}

	public LinguisticValue(String valueName) {
		this.name = valueName;

	}

	public Color getColor() {
		return color;
	}

	public void drawLine(Graphics g, double minX, double maxX, Color c) {
		if (points.size() == 0) {
			return;
		}
		Rectangle clip = g.getClipBounds();
		this.color = c;
		Point first = translateIntoClipPoint(points.get(0), minX, maxX, clip);
		int y = first.y;
		g.setColor(c);
		g.drawLine(0, y, first.x, first.y);
		g.drawString(String.valueOf(points.get(0).first), first.x - 10,
				(int) clip.getMaxY() - distanceOfXString);
		for (int i = 1; i < points.size(); i++) {
			Point p1 = translateIntoClipPoint(points.get(i - 1), minX, maxX,
					clip);
			Point p2 = translateIntoClipPoint(points.get(i), minX, maxX, clip);
			g.drawLine(p1.x, p1.y, p2.x, p2.y);
			g.drawString(String.valueOf(points.get(i).first), p2.x - 10,
					(int) clip.getMaxY() - distanceOfXString);
		}
		Point last = translateIntoClipPoint(points.get(points.size() - 1),
				minX, maxX, clip);
		g.drawLine((int) clip.getMaxX(), last.y, last.x, last.y);
		g.drawString(String.valueOf(points.get(points.size() - 1).first),
				last.x - 10, (int) clip.getMaxY() - distanceOfXString);
	}

	public double getMaxX() {
		if (points.size() > 0) {
			return points.get(points.size() - 1).first;
		} else {
			return 0;
		}

	}

	public double getMinX() {
		if (points.size() > 0) {
			return points.get(0).first;
		} else {
			return 0;
		}

	}

	private Point translateIntoClipPoint(Pair<Double, Double> p, double minX,
			double maxX, Rectangle clip) {
		double range = maxX - minX;
		double currentX = p.first - minX;
		double xPercent = currentX / range;
		double clipMaxY = clip.getMaxY() - 20;
		return new Point((int) ((clip.getMaxX() - clip.getMinX()) * xPercent),
				(int) (clipMaxY - p.second * (clipMaxY - clip.getMinY())));
	}

	public String getName() {
		return name;
	}

	public void addPoints(ArrayList<Pair<Double, Double>> list) {
		points.addAll(list);
		Collections.sort(points, new Comparator<Pair<Double, Double>>() {

			@Override
			public int compare(Pair<Double, Double> o1, Pair<Double, Double> o2) {
				return o1.first > o2.first ? 1 : -1;
			}

		});
	}

	public void removePoints(ArrayList<Pair<Double, Double>> list,
			Pair<Double, Double> rmovePair) {
		list.remove(rmovePair);
		points.addAll(list);

		Collections.sort(points, new Comparator<Pair<Double, Double>>() {

			@Override
			public int compare(Pair<Double, Double> o1, Pair<Double, Double> o2) {
				return o1.first > o2.first ? 1 : -1;
			}

		});
	}

	public void save() {
		if (ele != null) {
			ele.clearContent();
			ele.addAttribute("name", name);
			for (Pair<Double, Double> pair : points) {
				Element element = ele.addElement("point");
				element.addAttribute("x", String.valueOf(pair.first));
				element.addAttribute("y", String.valueOf(pair.second));
			}
		}
	}

}
